package com.california.payopenapi.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.california.pay.facade.MchOrderPayFacade;
import com.california.pay.model.PersonOrderPayReq;
import com.california.pay.model.PersonOrderPayRsp;
import com.california.pay.result.CommonResult;
import com.california.payopenapi.dao.OrderCreateQrCodeListDao;
import com.california.payopenapi.dao.PPayOrderDao;
import com.california.payopenapi.dao.PmchInfoDao;
import com.california.payopenapi.entity.OrderCreateQrCodeList;
import com.california.payopenapi.entity.PayOrderRequest;
import com.california.payopenapi.exception.SystemException;
import com.california.payopenapi.utils.BeanUtil;
import com.california.payopenapi.utils.PropertiesUtil;
import com.california.payopenapi.utils.QRCodeUtil;
import com.california.payopenapi.utils.TokensCacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description:
 * @author: KeyboardMan
 * @Date: Create in 2018-12-05:21:51
 */
@Slf4j
@Service
public class PayService {

    @Autowired
    CheckSignService checkSignService;

    @Reference
    MchOrderPayFacade mchOrderPayFacade;

    @Autowired
    PmchInfoDao pmchInfoDao;

    @Autowired
    PPayOrderDao orderDao;

    @Autowired
    OrderCreateQrCodeListDao qrCodeListDao;

    @Autowired
    TokensCacheUtil cacheUtil;

    private static final String ORDER_SUCCESS = "PAY_SUCC";


    private Map<String,String> tokens = new ConcurrentHashMap<>();


    public PersonOrderPayRsp getPayInfo(PayOrderRequest payOrder) {
        String secretKey = pmchInfoDao.getReqSecret(payOrder.getInnerMchNo());
        if (StringUtils.isEmpty(secretKey)) {
            throw new SystemException("商户不存在，请重新确认参数");
        }
        // 校验签名
        Map<String,Object> params;
        try {
            params = BeanUtil.getContext().obj2Map(payOrder);
        } catch (IntrospectionException e) {
            log.error("请码实体转换Map 异常 {}",e);
            throw new SystemException("交易平台内部错误，请稍后重试");
        } catch (InvocationTargetException e) {
            log.error("请码实体转换Map 异常 {}",e);
            throw new SystemException("交易平台内部错误，请稍后重试");
        } catch (IllegalAccessException e) {
            log.error("请码实体转换Map 异常 {}",e);
            throw new SystemException("交易平台内部错误，请稍后重试");
        }
        boolean signTrue = checkSignService.check(params,secretKey);
        if (!signTrue) {
            throw new SystemException("签名错误，请检查签名");
        }
        // 请求生成二维码参数
        PersonOrderPayReq personOrderPayReq = BeanUtil.getContext().payOrder2PersonOrderPayReq(payOrder);
        personOrderPayReq.setSystemTime(LocalDateTime.now());
        // 处理参数结果
        CommonResult<PersonOrderPayRsp> result = mchOrderPayFacade.personMchOrderPay(personOrderPayReq);
        if (result.isSuccess()) {
            // 发送成功回执
            PersonOrderPayRsp personOrderPayRsp = result.getResult();
            return personOrderPayRsp;
        } else {
            // 发送失败回执
            log.error("调用请求生成二维码接口异常 result :{} errMsg: {}",result,result.getErrmsg());
            throw new SystemException(result.getErrmsg());
        }
    }


    /**
     * 生成支付二维码
     * @param userId 用户编号
     * @param orderNo 订单编号
     * @param amount 金额
     * @return
     */
    public byte[] getPayQrCodeImg(String userId, String orderNo, Long amount) {
        // 校验是否已经生成二维码
        int count = qrCodeListDao.queryOrderIdIsCreate(orderNo);
        if (count == 1) {
            throw new SystemException("改订单已经生成二维码");
        }
        StringBuffer content = new StringBuffer();
        content.append(PropertiesUtil.getProperty("qrcode.str.pay_url"));
        String token = UUID.randomUUID().toString();
        content.append("/"+userId);
        content.append("/"+orderNo);
        content.append("/"+amount);
        content.append("/"+token);
        log.info("二维码数据 {}",content.toString());
        try {
            //String logoPath = getClass().getClassLoader().getResource("qrcode_logo.jpg").getPath();
            String logoPath = PropertiesUtil.getProperty("logo.img.url");
            byte[] bytes = QRCodeUtil.encode(content.toString(),logoPath,true);

            cacheUtil.put(orderNo,token);
           // tokens.put(orderNo,token);
            // 向生码记录表插入数据
            OrderCreateQrCodeList codeList = new OrderCreateQrCodeList();
            codeList.setOrderId(orderNo);
            codeList.setStatus(1);
            qrCodeListDao.insert(codeList);
            return bytes;
        } catch (Exception e) {
            log.error("生成支付二维码错误 {}",e);
            throw new SystemException("生成支付二维码错误,请稍后重试");
        }
    }

    /**
     * 校验二维码TOKEN
     * @param orderNo 订单编号
     * @param token token
     * @return
     */
    public boolean checkPay(String orderNo, String token) {
        String value;
        try {
            value = cacheUtil.getCache(orderNo);
            if (token.equals(value)) {
                // 缓存当场过期
                cacheUtil.invalidate(orderNo);
                return true;
            }
            return false;
        } catch (Exception e) {
            log.info("订单号 {} 已过期 返回订单TOKEN 异常  token = {}",orderNo,token);
            return false;
        }
        /*String value = tokens.get(orderNo);
        if (StringUtils.isNotEmpty(value)) {
            if (token.equals(value)) {
                tokens.remove(orderNo,token);
                return true;
            }
        }*/
    }

    public boolean orderIsSuccess(String orderId) {
        String orderStatus = orderDao.queryOrderStats(orderId);
        if (orderStatus != null && orderStatus.equals(ORDER_SUCCESS)) {
            return true;
        }
        return false;
    }


}